package com.sikaryofficial.common.core.annotation;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.sikaryofficial.common.core.enums.DataMaskingType;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Objects;

/**
 * @author : qinjinyuan
 * @desc : 脱敏序列化
 * @date : 2023/12/07 9:08
 */
@AllArgsConstructor
@NoArgsConstructor
public class DataMaskingSerialize extends JsonSerializer implements ContextualSerializer {

    private DataMaskingType type;

    private int start;

    private int end;


    private static String hiddenValue(String value, int start, int end) {
        if (value.length() < start) {
            start = 1;
        }
        if (value.length() < end) {
            end = value.length() - 1;
        }
        if (value.length() == 2) {
            end = value.length();
        }
        if (value.length() == 1) {
            start = 0;
            end = value.length();
        }
        return CharSequenceUtil.hide(value, start, end);
    }

    @Override
    public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String value1 = String.valueOf(value.toString());
        switch (type) {
            // userId
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.USER_ID)));
                break;
            // FIRST_MASK
            case FIRST_MASK:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.FIRST_MASK));
                break;
            // 中文名
            case CHINESE_NAME:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.CHINESE_NAME));
                break;
            // 身份证号
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.ID_CARD));
                break;
            // 座机
            case FIXED_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.FIXED_PHONE));
                break;
            // 手机号
            case MOBILE_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
                break;
            // 地址
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.ADDRESS));
                break;
            // 邮箱
            case EMAIL:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.EMAIL));
                break;
            // 银行卡
            case BANK_CARD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.BANK_CARD));
                break;
            // 密码
            case PASSWORD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.PASSWORD));
                break;
            // 中国大陆车牌号
            case CAR_LICENSE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.CAR_LICENSE));
                break;
            case IPV4:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.IPV4));
                break;
            case IPV6:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value1, DesensitizedUtil.DesensitizedType.IPV6));
                break;
            // 自定义
            case CUSTOM:
                jsonGenerator.writeString(hiddenValue(value1, start, end));
                break;
            default:
                break;
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (Objects.nonNull(beanProperty)) {
            //判断是否为string类型 | Long  | Integer
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)
                    || Objects.equals(beanProperty.getType().getRawClass(), Long.class)
                    || Objects.equals(beanProperty.getType().getRawClass(), Integer.class)) {
                DataMasking anno = beanProperty.getAnnotation(DataMasking.class);
                if (Objects.isNull(anno)) {
                    anno = beanProperty.getContextAnnotation(DataMasking.class);
                }
                if (Objects.nonNull(anno)) {
                    return new DataMaskingSerialize(anno.type(), anno.start(), anno.end());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}